package com.gc.controller;

import com.gc.common.constants.FileConstants;
import com.gc.common.constants.SysConstants;
import com.gc.common.resp.ApiResult;
import com.gc.common.util.MyUtil;
import com.gc.dto.ClientDTO;
import com.gc.dto.ReportDTO;
import com.gc.dto.UserDTO;
import com.gc.pojo.*;
import com.gc.services.*;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.catalina.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Controller
@RequestMapping("report")
public class ReportController {

    @Autowired
    private ReportService reportService;
    @Autowired
    private VorService vorService;
    @Autowired
    private UserService userService;
    @Autowired
    private ClientService clientService;


    @GetMapping("sign-view")
    public ModelAndView signView() {
        ModelAndView mav = new ModelAndView("report/sign");
        return mav;
    }

    @GetMapping("check-view")
    public ModelAndView checkView() {
        ModelAndView mav = new ModelAndView("report/check");
        return mav;
    }

    @GetMapping("submit-view")
    public ModelAndView submitView() {
        ModelAndView mav = new ModelAndView("report/submit");
        return mav;
    }

    @GetMapping("print-view")
    public ModelAndView printView() {
        ModelAndView mav = new ModelAndView("report/print");
        return mav;
    }

    @GetMapping("archive-view")
    public ModelAndView archiveView() {
        ModelAndView mav = new ModelAndView("report/archive");
        return mav;
    }

    @GetMapping("list-view")
    public ModelAndView listView() {
        ModelAndView mav = new ModelAndView("report/list");
        return mav;
    }

    @GetMapping("all-view")
    public ModelAndView allView() {
        ModelAndView mav = new ModelAndView("report/all");
        return mav;
    }

    @GetMapping("assign-view")
    public ModelAndView assignView() {
        ModelAndView mav = new ModelAndView("report/assign");
        List<UserDTO> shy = userService.getShy();
        mav.addObject("shys", shy);
        return mav;
    }

    @PostMapping("submit")
    @ResponseBody
    @Transactional
    public ApiResult submit(@RequestParam(value = "file") MultipartFile file, Integer vorId, String remark) {
        if (file.isEmpty()) {
            return new ApiResult(200, "文件不能为空！");
        }
        SysReport temp = reportService.getReportByVid(vorId);
        if (null != temp) {
            if (SysConstants.REPORT_STATUS4 == temp.getStatus()) {
                return new ApiResult(300, "报告已签发通过 , 无法重复提交");
            }
        }
        long tm = System.currentTimeMillis();
        int lastIndexOf = file.getOriginalFilename().lastIndexOf(".");
        String suffix = file.getOriginalFilename().substring(lastIndexOf);
        String filename = tm + suffix;
        try {
            //存文件
            File localFile = new File(FileConstants.REPORT_LOCAL_URL + filename);
            if (localFile.exists()) {
                return new ApiResult(500, "文件已存在！(文件名有重复)");
            }
            file.transferTo(localFile);
        } catch (IOException e) {
            e.printStackTrace();
            return new ApiResult(500, "文件上传失败！");
        }
        SysUser curUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        SysReport report = new SysReport();
        report.setCreateBy(curUser.getUserId());
        report.setPath(FileConstants.REPORT_VIRTUAL_URL + filename);
        report.setCreateTime(new Date());
        report.setRemark(remark);
        report.setStatus(SysConstants.REPORT_STATUS0);
        report.setVorId(vorId);
        try {
            int con1;
            // 验证原始记录是否有报告 , 重复提交是否覆盖 , 空模板上传时看是否已分配
            if (null != temp) {   // 当重复提交报告时 , 将会覆盖 , 先删除之前的报告文件
                new File(FileConstants.VOR_IMG_LOCAL_URL + temp.getPath()).delete();
                report.setReportId(temp.getReportId());
                con1 = reportService.modifyReport(report);
            } else {
                con1 = reportService.addReport(report);
            }
            int con2 = vorService.modifyVorStatusByVId(vorId, SysConstants.VOR_STATUS3);
            if (con1 != 1 || con2 != 1) {
                throw new Exception();
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();  //事物回滚
            return new ApiResult(500, "上传失败," + e);
        }
        return new ApiResult();
    }

    @GetMapping("getList")
    @ResponseBody
    public List<ReportDTO> getList(@RequestParam(required = false) Integer status, @RequestParam(required = false) Integer cid) {
        Subject subject = SecurityUtils.getSubject();
        boolean con1 = subject.hasRole(SysConstants.SYS_ROLE5);
        List<ReportDTO> list;
        if (con1) {
            //现场人员 , 只查询自己的列表数据  查询模板已分配的
            SysUser curUser = (SysUser) subject.getPrincipal();
            if (null != cid && cid != 0) {
                list = reportService.getMyReportListByCid(curUser.getUserId(), cid);
            } else {
                list = reportService.getMyReportList(curUser.getUserId());
            }
        } else {
            list = reportService.getAllReportList();
            if (null != cid && cid != 0) {
                list = list.stream().filter((reportDTO) -> cid.toString().equals(reportDTO.getClientId())).collect(Collectors.toList());
            }
            //在数据库中存的是 client的id , 页面展示时 ,需对应到client 的name
            Map<Integer, String> clientMap = clientService.getAllClient().stream()
                    .collect(Collectors.toMap(SysClient::getClientId, SysClient::getClientName,(k1, k2) -> k2));
            list.forEach((reportDTO) -> {
                reportDTO.setClientName(clientMap.get(Integer.valueOf(reportDTO.getClientId())));
            });
        }
        if (status != null) {
            list = list.stream().filter((report) -> status.equals(report.getStatus())).collect(Collectors.toList());
        }
        return list;
    }

    @GetMapping("get-check-list")
    @ResponseBody
    public List<ReportDTO> getCheckList(@RequestParam(required = false) Integer cid) {
        Subject subject = SecurityUtils.getSubject();
        SysUser curUser = (SysUser) subject.getPrincipal();
        List<ReportDTO> list = reportService.getCheckReportList();
        if(!subject.hasRole(SysConstants.SYS_ROLE1)){   //如果不是系统管理员 查看自己需要审核的报告
            list = list.stream().filter((report) ->
                    SysConstants.REPORT_STATUS1 == report.getStatus() &&
                            curUser.getUserId().equals(report.getCheckBy())
            ).collect(Collectors.toList());
        }
        if (cid != null && cid != 0) {
           list = list.stream().filter((reportDTO -> (cid.equals(Integer.valueOf(reportDTO.getClientId()))))).collect(Collectors.toList());
        }
        return list;
    }

    /**
     * 弃用
     */
    @GetMapping("get-sign-list")
    @ResponseBody
    public List<ReportDTO> getSignList() {
        List<ReportDTO> list = reportService.getCheckReportList();
        list = list.stream().filter((report) -> SysConstants.REPORT_STATUS2 == report.getStatus())
                .collect(Collectors.toList());
        return list;
    }

    /**
     * 弃用
     */
    @GetMapping("get-archive-list")
    @ResponseBody
    public List<ReportDTO> getArchiveList() {
        List<ReportDTO> list = reportService.getCheckReportList();
        list = list.stream().filter((report) -> SysConstants.REPORT_STATUS6 == report.getStatus())
                .collect(Collectors.toList());
        return list;
    }

    @GetMapping("get-print-list")
    @ResponseBody
    public List<ReportDTO> getPrintList() {
        List<ReportDTO> list = reportService.getPrintReportList();
        list = list.stream().filter((report) -> SysConstants.REPORT_STATUS4 == report.getStatus()).collect(Collectors.toList());
        return list;
    }

    @GetMapping("get-all-list")
    @ResponseBody
    public List<ReportDTO> getAllList() {
        List<ReportDTO> list = reportService.getAllReportList();
        return list;
    }

    @PostMapping("modify-shy")
    @ResponseBody
    public ApiResult modifyShy(@RequestParam Integer rid, @RequestParam Integer shyId) {
        try {
            int count = reportService.modifyShyByRid(rid, shyId);
            int count2 = reportService.modifyStatusByRid(rid, SysConstants.REPORT_STATUS1);
            if (count != 1 || count2 != 1) {
                throw new Exception();
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ApiResult(200, "操作失败!");
        }
        return new ApiResult();
    }

    @PostMapping("check-pass")
    @ResponseBody
    public ApiResult checkPass(@RequestParam Integer rid) {
        int count = reportService.checkPassReportByRid(rid, SysConstants.REPORT_STATUS2);
        return new ApiResult();
    }

    @PostMapping("check-reject")
    @ResponseBody
    public ApiResult checkPass(@RequestParam Integer rid, @RequestParam String msg) {
        int count = reportService.checkRejectReportByRid(rid, msg, SysConstants.REPORT_STATUS3);
        return new ApiResult();
    }

    @PostMapping("sign-pass")
    @ResponseBody
    public ApiResult signPass(@RequestParam Integer rid) {
        try {
            //签发后 ....
           boolean con =  reportService.signPassReportByRid(rid, SysConstants.REPORT_STATUS4);
        } catch (Exception e) {
            e.printStackTrace();
            return new ApiResult(500, "操作失败!");
        }
        return new ApiResult();
    }

    @PostMapping("sign-reject")
    @ResponseBody
    public ApiResult signPass(@RequestParam Integer rid, @RequestParam String msg) {
        int count = reportService.signRejectReportByRid(rid, msg, SysConstants.REPORT_STATUS5);
        return new ApiResult();
    }
}